// lib/main.dart
import 'dart:async';
import 'dart:typed_data';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_blue_plus/flutter_blue_plus.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:syncfusion_flutter_charts/charts.dart';
import 'speed_chart_page.dart'; // 导入 speed_chart_page.dart

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  // 允许横竖屏
  SystemChrome.setPreferredOrientations([
    DeviceOrientation.portraitUp,
    DeviceOrientation.landscapeLeft,
    DeviceOrientation.landscapeRight,
  ]);
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'BLE Speed',
      theme: ThemeData.dark(),
      home: const ConsolePage(),
    );
  }
}

/* ------------------------------------------
   控制台页面（竖屏）
------------------------------------------ */
class ConsolePage extends StatefulWidget {
  const ConsolePage({Key? key}) : super(key: key);

  @override
  State<ConsolePage> createState() => _ConsolePageState();
}

class _ConsolePageState extends State<ConsolePage> with WidgetsBindingObserver {
  final List<String> _logs = [];
  final List<ScanResult> _results = [];
  StreamSubscription<List<int>>? _notifySubscription;

  // 上轮数据缓存
  int? _lastRev;
  int? _lastTimeRaw;

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
    _checkPermissionsAndStart();
  }

  @override
  void dispose() {
    _notifySubscription?.cancel();
    FlutterBluePlus.stopScan();
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }

  /* ---------- 权限 & 扫描 ---------- */
  Future<void> _checkPermissionsAndStart() async {
    final statuses = await [
      Permission.bluetoothScan,
      Permission.bluetoothConnect,
      Permission.location,
    ].request();
    if (!statuses.values.every((s) => s.isGranted)) {
      _log('❌ 权限不足');
      return;
    }
    _log('✅ 权限 OK，开始扫描…');
    _startScan();
  }

  void _startScan() {
    FlutterBluePlus.startScan(timeout: const Duration(seconds: 10));
    FlutterBluePlus.scanResults.listen((results) => setState(() {
      _results.assignAll(results);
    }));
  }

  /* ---------- 连接 & 订阅 ---------- */
  Future<void> _onTapDevice(BluetoothDevice device) async {
    _log('👉 点击 ${device.remoteId}');
    await device.connect(timeout: const Duration(seconds: 10));
    _log('🔗 已连接');

    final services = await device.discoverServices();
    final cscSvc = services.firstWhere(
          (s) => _shortUuid(s.uuid) == '1816',
      orElse: () => throw '未找到 0x1816',
    );
    _log('✅ 找到 0x1816 服务');

    final cscChar = cscSvc.characteristics.firstWhere(
          (c) => _shortUuid(c.uuid) == '2a5b',
      orElse: () => throw '未找到 0x2A5B',
    );

    await cscChar.setNotifyValue(true);
    _log('🔔 已订阅 notify');

    _notifySubscription = cscChar.lastValueStream.listen((bytes) {
      _log('📥 NOTIFY: ${_prettyHex(bytes)}');
      final (dRev, dT) = _parseDelta(bytes);
      if (dT > 0) {
        speedChartKey.currentState?.addRawData(dRev, dT);
      }
    });
  }

  /* ---------- 计算 Δrev / Δt ---------- */
  (int deltaRev, double deltaTimeSec) _parseDelta(List<int> bytes) {
    if (bytes.length < 7) return (0, 0);
    if ((bytes[0] & 0x01) == 0) return (0, 0);

    final rev = ByteData.sublistView(Uint8List.fromList(bytes.sublist(1, 5)))
        .getUint32(0, Endian.little);
    final timeRaw = ByteData.sublistView(Uint8List.fromList(bytes.sublist(5, 7)))
        .getUint16(0, Endian.little);

    if (_lastRev == null || _lastTimeRaw == null) {
      _lastRev = rev;
      _lastTimeRaw = timeRaw;
      return (0, 0);
    }

    int dRev = rev - _lastRev!;
    int dRaw = timeRaw - _lastTimeRaw!;
    if (dRaw < 0) dRaw += 0x10000;
    final dSec = dRaw / 1024.0;

    _lastRev = rev;
    _lastTimeRaw = timeRaw;
    return (dRev, dSec);
  }

  /* ---------- 日志 ---------- */
  void _log(String txt) {
    final ts = TimeOfDay.now().format(context);
    setState(() => _logs.add('[$ts] $txt'));
  }

  /* ---------- 横竖屏监听 ---------- */
  @override
  void didChangeMetrics() {
    super.didChangeMetrics();
    final size = MediaQuery.of(context).size;
    final isLandscape = size.width > size.height;
    if (isLandscape && ModalRoute.of(context)?.settings.name != '/speed') {
      Navigator.push(
        context,
        MaterialPageRoute(
          builder: (_) => SpeedChartPage(key: speedChartKey),
        ),
      );
    } else if (!isLandscape && ModalRoute.of(context)?.settings.name == '/speed') {
      Navigator.pop(context);
    }
  }

  /* ---------- UI ---------- */
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('BLE Console')),
      body: Row(
        children: [
          // 左侧列表
          SizedBox(
            width: 200,
            child: ListView.builder(
              itemCount: _results.length,
              itemBuilder: (_, idx) {
                final r = _results[idx];
                final name =
                r.device.platformName.isEmpty ? '(未知)' : r.device.platformName;
                return ListTile(
                  title: Text(name),
                  subtitle: Text(r.device.remoteId.str),
                  onTap: () => _onTapDevice(r.device),
                );
              },
            ),
          ),
          const VerticalDivider(width: 1),
          // 右侧日志
          Expanded(
            child: ListView.builder(
              reverse: true,
              itemCount: _logs.length,
              itemBuilder: (_, idx) => Padding(
                padding: const EdgeInsets.all(4),
                child: Text(_logs[_logs.length - 1 - idx],
                    style: const TextStyle(fontSize: 12)),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

/* ------------------------------------------
   速度图表页面（横屏）
------------------------------------------ */
// 全局 key，用于把数据喂给 State
// final GlobalKey<_SpeedChartPageState> speedChartKey =
// GlobalKey<_SpeedChartPageState>();

// class SpeedChartPage extends StatefulWidget {
//   const SpeedChartPage({Key? key}) : super(key: key);
//
//   @override
//   State<SpeedChartPage> createState() => _SpeedChartPageState();
// }

// class _SpeedChartPageState extends State<SpeedChartPage> {
//   final List<SpeedPoint> _points = [];
//   Timer? _timer;
//   static const wheelCircumference = 2.105; // 轮周长，单位米
//
//   @override
//   void initState() {
//     super.initState();
//     // 每秒清理老数据并重绘
//     _timer = Timer.periodic(const Duration(seconds: 1), (_) {
//       final cutoff = DateTime.now().subtract(const Duration(seconds: 15));
//       setState(() => _points.removeWhere((p) => p.ts.isBefore(cutoff)));
//     });
//   }
//
//   @override
//   void dispose() {
//     _timer?.cancel();
//     super.dispose();
//   }
//
//   // 外部调用入口
//   void addRawData(int deltaRev, double deltaTimeSec) {
//     if (deltaTimeSec <= 0) return;
//     final speed = wheelCircumference * deltaRev / deltaTimeSec;
//     setState(() => _points.add(SpeedPoint(DateTime.now(), speed)));
//   }
//
//   double get _currentSpeed => _points.isEmpty ? 0 : _points.last.speedMs;
//
//   @override
//   Widget build(BuildContext context) {
//     return Scaffold(
//       backgroundColor: Colors.black,
//       body: Column(
//         children: [
//           Expanded(
//             flex: 2,
//             child: Center(
//               child: Text(
//                 '${_currentSpeed.toStringAsFixed(2)} m/s',
//                 style: const TextStyle(
//                     fontSize: 72,
//                     fontWeight: FontWeight.bold,
//                     color: Colors.white),
//               ),
//             ),
//           ),
//           Expanded(
//             flex: 3,
//             child: SfCartesianChart(
//               plotAreaBorderWidth: 0,
//               primaryXAxis: DateTimeAxis(
//                 isVisible: false,
//                 intervalType: DateTimeIntervalType.seconds,
//               ),
//               primaryYAxis: NumericAxis(
//                 title: const AxisTitle(text: 'Speed (m/s)'),
//                 labelStyle: const TextStyle(color: Colors.white),
//               ),
//               series: <LineSeries<SpeedPoint, DateTime>>[
//                 LineSeries<SpeedPoint, DateTime>(
//                   dataSource: _points,
//                   xValueMapper: (p, _) => p.ts,
//                   yValueMapper: (p, _) => p.speedMs,
//                   color: Colors.cyanAccent,
//                   width: 3,
//                 ),
//               ],
//             ),
//           ),
//         ],
//       ),
//     );
//   }
// }

/* ------------------------------------------
   工具函数
------------------------------------------ */
String _shortUuid(Guid uuid) {
  final str = uuid.str.toLowerCase();
  if (str.length == 36 &&
      str.startsWith('0000') &&
      str.endsWith('-0000-1000-8000-00805f9b34fb')) {
    return str.substring(4, 8);
  }
  return str;
}

String _prettyHex(List<int> bytes) =>
    bytes.map((b) => b.toRadixString(16).padLeft(2, '0')).join(' ');

extension ListExt<T> on List<T> {
  void assignAll(Iterable<T> other) {
    clear();
    addAll(other);
  }
}

// 车速数据点
class SpeedPoint {
  final DateTime ts;
  final double speedMs;
  SpeedPoint(this.ts, this.speedMs);
}